home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 9 / Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO / 042a / swagn_r.zip / NUMBERS.SWG < prev    next >
Text File  |  1993-05-28  |  49KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00024         BITWISE TRANSLATIONS ROUTINES                                     1      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BITS1.PAS                IMPORT              14          {π Sean Palmerππ> What if I want to just access a bit?  Say I have a Byte, to storeπ> Various access levels (if it does/doesn't have this, that, or theπ> other).  How can Iππ> 1)  Access, say, bit 4?π> 2)  Give, say, bit 4, a value of 1?ππ> I have a simple routine that does "GetBit:= Value SHR 1;" to returnπ> a value, but how can I *SET* a value?  And is the above a goodπ> method? I only have TP5.5, so I can't do the Asm keyWord (yet..).ππYou COULD use TP sets to do it...π}ππTypeπ  tByte = set of 0..7;πVarπ  b : Byte;ππ{to get:π  Write('Bit 0 is ',Boolean(0 in tByte(b)));ππto set:π  tByte(b):=tByte(b)+[1,3,4]-[0,2];π}ππTypeπ  bitNum = 0..7;π  bit    = 0..1;ππFunction getBit(b : Byte; n : bitNum) : bit;πbeginπ  getBit := bit(odd(b shr n));πend;ππFunction setBit( b : Byte; n : bitNum) : Byte;πbeginπ  setBit := b or (1 shl n);πend;ππFunction clrBit(b : Byte; n : bitNum) : Byte;πbeginπ  clrBit := b and hi($FEFF shl n);πend;ππ{π OR.....using Inline() code  (the fastest)π These are untested but I'm getting fairly good at assembling by hand...8)π}ππFunction getBit(b : Byte; n : bitNum) : bit;πInline(π  $59/      {pop cx}π  $58/      {pop ax}π  $D2/$E8/  {shr al,cl}π  $24/$01); {and al,1}ππFunction setBit(b : Byte; n : bitNum) : Byte;πInline(π  $59/      {pop cx}π  $58/      {pop ax}π  $B3/$01/  {mov bl,1}π  $D2/$E3/  {shl bl,cl}π  $0A/$C3); {or al,bl}ππFunction clrBit(b : Byte; n : bitNum) : Byte;πInline(π  $59/      {pop cx}π  $58/      {pop ax}π  $B3/$FE/  {mov bl,$FE}π  $D2/$C3/  {rol bl,cl}π  $22/$C3); {or al,bl}π                                                                                                                                2      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BITS2.PAS                IMPORT              25          {πROB GREENππ> What if I want to just access a bit?  Say I have a Byte, to storeπ> Various access levels (if it does/doesn't have this, that, or theπ> other).  How can Iπ> 1)  Access, say, bit 4?π> 2)  Give, say, bit 4, a value of 1?ππHeres a Procedure i wrote to handle all that.  if you need speed, thenπi suggest to manually check each bit, rather than use the Procedures.ππ(these Procedures are based on 1, not 0.  thus each Byte is like so:π87654321   instead of 76543210.  to change to 0 base, change the Array toπ[0..31] instead of [1..32].)ππto set a bit: (b is an Integer Type, BIT is which bit to setπ   b:=b or BIT;   ex: b:=b or 128  (set bit 8)ππto clear a bit:π   b:=b and not BIT;  ex:b:=b and not 8;  (clears bit 4)ππto check a bit:π   if b and BIT<>0 then..  ex:if b and 64 then..  (check bit 7)π}ππConstπ{ Used to convert the Bit value to the actual corresponding number }π   bit : Array[1..32] of LongInt =π       (1, 2, 4, 8, $10, $20, $40, $80, $100, $200, $400, $800, $1000, $2000,π        $4000, $8000, $10000, $20000, $40000, $80000, $100000, $200000,π        $400000, $800000, $1000000, $2000000, $4000000, $8000000, $10000000,π        $20000000, $40000000, $80000000);ππ{b is which bit to set(1-32), size is the size of temp.πUse  SIZEOF(TEMP) to get the value, and temp is the actuall Integer basedπnumberπreturns True if bit set, False if not}ππFunction checkbit(b : Byte; size : Byte; Var temp) : Boolean; {1-32}πVarπ  c : Boolean;πbeginπ   c:=False;π   Case size ofπ     1 : c := Byte(temp) and bit[b] <> 0;     {Byte,shortint}π     2 : c := Word(temp) and bit[b] <> 0;     {Word,Integer}π     4 : c := LongInt(temp) and bit[b] <> 0;  {LongInt}π     elseπ       Writeln('Invalid size');π   end;π   checkbit := c;πend;ππ{b,size,and temp same as above.  if onoff =True the bit will be set,πelse the bit will be cleared}ππProcedure setbit(b : Byte; onoff : Boolean; size : Byte; Var temp); {1-32}πbeginπ   if onoff thenπ   Case size ofπ     1 : Byte(temp) := Byte(temp) or bit[b];        {Byte}π     2 : Word(temp) := Word(temp) or bit[b];        {Word}π     4 : LongInt(temp) := LongInt(Temp) or bit[b];  {LongInt}π     elseπ       Writeln('Invalid size');π   endπ   elseπ   Case size ofπ     1 : Byte(temp) := Byte(temp) and not bit[b];   {Byte}π     2 : Word(temp) := Word(temp) and not bit[b];   {Word}π     4 : LongInt(temp) := LongInt(Temp) and not bit[b];{LongInt}π     elseπ       Writeln('Invalid size');π   end;πend;ππ{this is a sample test Program i wrote For you to see how to use theπstuff above}ππVarπ  i : LongInt;π  j : Byte;πbeginπ   i := 0;π   setbit(4,True,sizeof(i),i);  {8}π   Writeln(i);π   setbit(9,True,sizeof(i),i);  {256+8 = 264}π   Writeln(i);π   setbit(9,False,sizeof(i),i); {8}π   Writeln(i);π   setbit(20,True,sizeof(i),i); { $80000+8 = $80008}π   Writeln(i);π   For i := 65550 to 65575 doπ   beginπ     Write(i : 8, ' = ');π     For j := 32 downto 1 do {to print right}π       if checkbit(j, sizeof(i), i) thenπ         Write('1')π       elseπ         Write('0');π     Writeln;π   end;πend.π                       3      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BIT_GET.PAS              IMPORT              3           { You can use multiplies of 2 like: }ππFunction Find_Bit(B, c : Byte) : Byte;π{c is the position c=0 far right c=7 far leftπreturns 0 or 1}πbeginπ if b MOD (b shl c) = 0 then Find_Bit := 0π  else Find_Bit := 1πend;ππ                                        4      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BIT_ROT1.PAS             IMPORT              8           The commands you need to rotate a Byte/Word are:ππROR, ROL, RCR, RCL.πROR ==> Rotates the bits the number of times specified, so that theπ        rightmost bits are rotated into the leftmost bits.  NO BITSπ        ARE LOST.  ROL is the same thing in the opposite direction.ππRCR ==> Practically the same as the ROR/ROL instruction, but it rotatesπ        the bit into the carry, and the carry bit is rotated into theπ        leftmost bit of the Byte/Word.  {Rotate right through carry}π        RCL is the same in the other direction.ππThe format For each of ROR,ROL,RCR,RCL,SHR,SHL isππ  [Instruction]  <Destination>  <Shift Count>ππTo reWrite your original code:ππAsmπ  Mov  AL, ByteVarπ  Ror  AL, 1π  Mov  ByteVar, ALπendππThe above would rotate the bits in the Variable ByteVar by one to the right.π                                                                                              5      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BIT_ROT2.PAS             IMPORT              14          > I made a Program in Turbo-Pascal that rotates the bits in one Byte so I canπ> encrypt/decrypt a File, however the routine is slow. I then made the sameπ> Program in turbo-C using _RotLeft and _RotRight, the speed of execution wasπ> Really faster than Turbo-Pascal. Does anybody know of a way to rotate theπ> bits of one Byte in turbo-Pascal and FAST !!!!πππ        Since 80xxx CPUs have bit rotate instructions (ROL, ROR), it wouldπbe a shame to use some clumsy HLL Construct. BTW, I'm sure _RotLeft andπ_RotRight use rotate instructions too, possibly insert them Inline. Ifπyou are using TP 6.0+, try something like this:ππ{ to rotate left }πFunction RotLeft(B, Count: Byte): Byte; Assembler;πAsmπ  mov   al, Bπ  mov   cl, Countπ  rol   al, clπend;ππ{ to rotate right }πFunction RotRight(B, Count: Byte): Byte; Assembler;πAsmπ  mov   al, Bπ  mov   cl, Countπ  ror   al, clπend;πππ        Of course, if you need to do this in only a few places it wouldπbe better not to define Functions, but insert Asm blocks in your codeπdirectly.ππ        The fastest Pascal way to rotate Byte would be something likeπthis:ππFunction RotLeft(B, Count: Byte): Byte;πVarπ  W : Word;π  A : Array[0..1] of Byte Absolute W;πbeginπ  A[0] := B;π  A[1] := B;π  W := W shl Count;π  RotLeft := A[1];πend;ππ        To rotate right With this method, you would shift right andπreturn A[0]. I would like to think this is as fast as it gets in TPπwithout assembly, but one can never be sure <g>. Anyway, I recommendπthe assembly solution over this one, it is faster and more elegant.π                                                                                                           6      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BIT_ROT3.PAS             IMPORT              5           {πSEAN PALMERπ}ππFunction rolW(b : Word; n : Byte) : Word; Assembler;πAsmπ  mov ax, bπ  mov cl, nπ  rol ax, clπend;ππFunction rolB(b, n : Byte) : Byte; Assembler;πAsmπ  mov al, bπ  mov cl, nπ  rol al, clπend;ππFunction rolW1(b : Word) : Word; Assembler;πAsmπ  mov ax, bπ  rol ax, 1πend;ππ{ These would be better off as Inline Functions, such as... }ππFunction IrolW1(b : Word) : Word;πInline(π  $58/          {pop ax}π  $D1/$C0);     {rol ax,1}ππ{ because no Function call is generated. }ππ                      7      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BYT2REAL.PAS             IMPORT              5           Typeπ  bsingle = Array [0..3] of Byte;ππ{ converts Microsoft 4 Bytes single to TP Real }ππFunction msb_to_Real (b : bsingle) : Real;πVarπ  pReal : Real;π  r     : Array [0..5] of Byte Absolute pReal;πbeginπ  r [0] := b [3];π  r [1] := 0;π  r [2] := 0;π  move (b [0], r [3], 3);π  msb_to_Real := pReal;πend; { Function msb_to_Real }ππ{πAnother Turbo Pascal routine to convert Microsoft single to TP LongIntππindex := ((mssingle and not $ff000000) or $00800000) shr (24 -π((mssingle shr 24) and $7f)) - 1;π}π      8      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BYTE2BIN.PAS             IMPORT              7           {πByte to Binary...π}ππTypeπ  String8 = String[8];πππFunction Byte2Bin(byTemp : Byte) : String8;πVarπ  Count : Integer;πbeginπ  Byte2Bin[0] := #8;π  For Count := 0 to 7 doπ    Byte2Bin[8 - Count] := Char(((byTemp shr Count) and 1) + ord('0'));πend;ππFunction Byte2BinAsm(byTemp : Byte) : String8; Assembler;πAsmπ  push    dsπ  les     di,@resultπ  mov     ah,byTempπ  mov     cl,8π  mov     al,clπ  stosbπ@loop:π  mov     al,24π  add     ah,ahπ  adc     al,alπ  stosbπ  loop    @loopπ  pop     dsπend;ππbeginπ  Writeln;π  Writeln('10 in Binary = ',Byte2Bin(10));π  Writeln;π  Writeln('The same thing With assembly code: ',Byte2BinAsm(10));π  Writeln;π  Readln;πend.                                                                                                       9      05-28-9313:53ALL                      SWAG SUPPORT TEAM        BYTEINFO.PAS             IMPORT              57          {π>Also, how would I simply read each bit?π}π{ Test if a bit is set. }πFunction IsBitSet(Var INByte : Byte; Bit2Test : Byte) : Boolean;πbeginπ  if (Bit2Test in [0..7]) thenπ    IsBitSet := ((INByte and (1 shl Bit2Test)) <> 0)π  elseπ    Writeln('ERROR! Bit to check is out of range!');πend; { IsBitSet. }ππ{π>How on earth can I manipulate an individual bit?ππ...One method is to use the bit-operators:  AND, OR, XOR, NOTπ}ππ{ Manipulate an individual BIT within a single Byte. }πProcedure SetBit(Bit2Change : Byte; TurnOn : Boolean; Var INByte : Byte);πbeginπ  if Bit2Change in [0..7] thenπ  beginπ    if TurnOn thenπ      INByte := INByte or (1 shl Bit2Change)π    elseπ      INByte := INByte and NOT(1 shl Bit2Change);π  end;πend; { SetBit. }ππ{π>...but I'm not sure exactly what the shifting is doing.π}ππ    { Check if the bit is to be turned on or off. }π    If TurnOn thenππ    {π      SHL 1 (which has a bit map of 0000 0001) to the bitπ      position we want to turn-on.ππ        ie: 1 SHL 4 = bit-map of 0001 0000ππ      ...Then use a "logical OR" to set this bit.ππ      ie: Decimal:     2      or      16     =    18π          Binary : 0000 0010  or  0001 0000  = 0001 0010π    }ππ      INByte := INByte or (1 shl Bit2Change)π    elseππ    {π      Else turn-off bit.ππ      SHL 1 (which has a bit map of 0000 0001) to the bitπ      position we want to turn-off.ππ         ie: 1 SHL 4 = bit-map of 0001 0000ππ       ...Then use a "logical NOT" to flip all the bits.ππ       ie: Decimal:  not (   16    ) =      239π           Binary :  not (0001 0000) =  (1110 1111)ππ       ...Than use a "logical AND" to turn-off the bit.ππ       ie: Decimal:     255     and     239    = 239π           Binary :  1111 1111  and  1110 1111 = 1110 1111π    }ππ     INByte := INByte and NOT(1 shl Bit2Change);ππ{π>Also, how can you assign a Byte (InByte) a Boolean value (OR/AND/NOT)ππ  or / xor / and / not are "logical" bit operators, that can be use onπ  "scalar" Types. (They also Function in the same manner For "Boolean"π  logic.)ππ>If I have, say 16 bits in one Byte, the interrupt list says that forπ>instance the BIOS calls (INT 11), AX is returned With the values. Itπ>says that the bits from 9-11 tell how many serial portss there are.π>How do I read 3 bits?ππ  To modify the two routines I posted wo work With 16 bit Variables,π  you'll need to change:ππ     INByte : Byte;  --->  INWord : Word;ππ  ...Also:ππ     in [0..7]  --->  in [0..15]ππ  ...If you don't want to use the IsBitSet Function listed aboveπ  (modified to accept 16-bit Word values) you could do the followingπ  to check if bits  9, 10, 11 are set in a 16-bit value:ππ  The following is the correct code For reading bits 9, 10, 11π  of the 16-bit Variable "AX_Value" :ππ      Port_Count :=  ((AX_Value and $E00) SHR 9);ππ    NOTE: Bit-map For $E00 = 0000 1110 0000 0000ππ  ...If you've got a copy of Tom Swan's "Mastering Turbo Pascal",π  check the section on "logical operators".πππ{π>Var Regs : Registers;π>beginπ>  Intr($11,Regs);π>  Writeln(Regs.AX);π>end.ππ>How do I manipulate that to read each bit (or multiple bits likeπ>the number of serial ports installed (bits 9-11) ?π}ππUsesπ  Dos;ππVarπ  Port_Count : Byte;π  Regs       : Registers;ππbeginπ  Intr($11, Regs);π  Port_Count := ((Regs.AX and $E00) SHR 9);π  Writeln('Number of serial-ports = ', Port_Count)πend.π{πNOTE: The hex value of $E00 is equivalent to a 16-bit value withπ      only bits 9, 10, 11 set to a binary 1. The SHR 9 shifts theπ      top Byte of the 16-bit value, to the lower Byte position.π}π{π>Is $E00 the same as $0E00 (ie, can you just omit leading zeros)?ππYeah, it's up to you if you want to use the leading zeros or not.ππThe SHR 9 comes in because once the value has been "AND'd" withπ$E00, the 3 bits (9, 10, 11) must be placed at bit positions:π0, 1, 2  ...to correctly read their value.ππFor example, say bits 9 and 11 were set, but not bit 10. If weπ"AND" this With $E00, the result is $A00.ππ1011 1010 0111 1110  and  0000 1110 0000 0000  =  0000 1010 0000 0000π       ^ ^π(bits 9,11 are set)  and  (      $E00       )  =  $A00π...Taking the result of $A00, and shifting it right 9 bit positionsππ         $A00         SHR 9  =           5ππ 0000 1010 0000 0000  SHR 9  =  0000 0000 0000 0101ππ...Which evalutates to 5. (ie: 5 serial ports)π}ππππππππππ{πGet Equipment Bit-Mapπ---------------------ππ         AH       ALπ      76543210 76543210πAX =  ppxgrrrx ffvvmmciππ...π...πrrr = # of RS232 ports installedπ...π...ππ (* reports the number of RS232 ports installed *)πFunction NumRS232 : Byte;πVar Regs : Registers;                 (* Uses Dos *)πbeginπ  Intr($11,Regs);π  NumRS232 := (AH and $0E) shr 1;πend;πππ...When you call Int $11, it will return the number of RS232 ports installedπin bits 1-3 in register AH.ππFor example if AH = 01001110 , you can mask out the bits you *don't* wantπby using AND, like this:ππ              01001110      <---  AHπ        and   00001110      <---- mask $0Eπ        ──────────────π              00001110      <---- after maskingπππThen shift the bits to the right With SHR,ππ              00001110      <---- after maskingπ         SHR         1      <---- shift-right one bit positionπ         ─────────────π              00000111      <---- result you wantπ}ππ{π-> How do I know to use $4 For the third bit?  Suppose I want to readπ-> the fifth bit. Do I simply use b := b or $6?ππ    Binary is a number system just like decimal.  Let me explain.πFirst, consider the number "123" in decimal.  What this means,πliterally, isππ1*(10^2) + 2*(10^1) + 3*(10^0), which is 100 + 20 + 3.ππ    Binary works just the same, however instead of a 10, a 2 is used asπthe base.  So the number "1011" meansππ1*(2^3) + 0*(2^2) + 1*(2^1) + 1*(2^0), or 8+0+2+1, or 11.ππ     This should make it clear why if you wish to set the nth bit toπTrue, you simply use a number equal to 2^(n-1).  (The -1 is thereπbecause you probably count from 1, whereas the powers of two, as you mayπnote, start at 0.)ππ-> b or (1 SHL 2) Would mean that b := 1 (True) if b is already equal toπ-> one (1) and/OR the bit two (2) to the left is one (1) ???ππ    Aha.  You are not familiar With bitwise or operations.  When oneπattempts to or two non-Boolean values (Integers), instead of doing aπlogical or as you are familiar with, each individual BIT is or'd.  I.E.πimagine a Variables A and B had the following values:ππa := 1100 (binary);πb := 1010 (binary);ππthen, a or b would be equal to 1110 (binary);  Notice that each bit of aπhas been or'd With the corresponding bit of b?  The same goes For and.πHere's an example.ππa := 1100 (binary);πb := 1010 (binary);ππa and b would be equal to 1000;ππI hope this clears up the confusion.  And just to be sure, I'm going toπbriefly show a SHL and SHR operation to make sure you know.  Considerπthe numberππa := 10100 (binary);ππThis being the number, A SHL 2 would be equal to 1010000 (binary) --πnotice that it has been "shifted to the left" by 2 bits.ππA SHR 1 would be 1010 (binary), which is a shifted to the right by 2πbits.π}ππ                                                                                                                         10     05-28-9313:53ALL                      SWAG SUPPORT TEAM        DEC2BIN1.PAS             IMPORT              6           {π>  I need to transfer decimal into binary using TURBO PASCAL.π>  One way to do this is to use the basic algorithm, dividingπ>  by 2 over and over again. if the remainder is zero theπ>  bit is a 0, else the bit is a 1.π>π>  However, I was wondering if there is another way to convertπ>  from decimal to binary using PASCAL. Any ideas?ππAs an 8-bit (ie. upto 255) example...π}ππ  Function dec2bin(b:Byte) : String;π  Var bin : String[8];π      i,a : Byte;π  beginπ   a:=2;π   For i:=8 downto 1 doπ    beginπ     if (b and a)=a then bin[i]:='1'π                    else bin[i]:='0';π     a:=a*2;π    end;π    dec2bin:=bin;π  end;ππ          11     05-28-9313:53ALL                      SWAG SUPPORT TEAM        DEC2BIN2.PAS             IMPORT              7           { True so here is another version of the process that returns a String : }ππProgram Dec2BinRec;ππTypeπ  Str32 = String[32];ππFunction Dec2BinStr(aNumber : LongInt) : Str32;ππ  Function Bit(aBit : Byte) : Char;π  (* return either Char '0' or Char '1' *)π  beginπ    if aBit = 0 thenπ      Bit := '0'π    elseπ      Bit := '1'π  end;ππbeginπ  If aNumber = 0 Thenπ    Dec2BinStr := ''   (* done With recursion ?*)π  else                                (* convert high bits + last bit *)π    Dec2BinStr := Dec2BinStr(ANumber Div 2) + Bit(aNumber Mod 2);πend;ππVarπ  L : LongInt;πbeginπ  Repeatπ    Readln (L);π    If L <> 0 thenπ      Writeln(Dec2BinStr(L));π  Until (L = 0)πend.π                                                                                            12     05-28-9313:53ALL                      SWAG SUPPORT TEAM        HEX2BIN1.PAS             IMPORT              22          Function Hex2Bin (B : Byte) : String;ππVarπ  Temp : String [8];π  Pos, Mask : Byte;ππbeginπ  Temp := '00000000';π  Pos := 8;π  Mask := 1;π  While (Pos > 0) Doπ    beginπ      if (B and Mask)π        thenπ          Temp [Pos] := '1';π      Dec (Pos);π      Mask := 2 * Mask;π    end;π  Hex2Bin := Temp;πend;ππππππππFunction Hex2Bin( HexByte:Byte ):String; External; {$L HEX2Bin.OBJ}πVar i : Integer;πbeginπ  For i := $00 to $0F do WriteLn( Hex2Bin(i) );πend.π(*********************************************************************)ππ The Assembly source ...ππ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;πcode        segment Byte 'CODE'     ; HEX2Bin.Asmπ            assume  cs:codeπ; Function Hex2Bin( HexByte :Byte ) :String;πString      equ     dWord ptr [bp+6]πHexByte     equ     [bp+4]π            public  Hex2BinπHex2Bin     proc    Near            ; link into main TP Programπ            push    bp              ; preserveπ            mov     bp,sp           ; stack frameπ            les     di, String      ; result String Pointerπ            cld                     ; Forward scanπ            mov     cx,8            ; 8 bits in a Byteπ            mov     al,cl           ; to setπ            stosb                   ; binary String lengthπ            mov     ah, HexByte     ; get the hex Byteπ    h2b:    xor     al,al           ; cheap zeroπ            rol     ax,1            ; high bit to low bitπ            or      al,'0'          ; make it asciiπ            stosb                   ; put it in Stringπ            loop    h2b             ; get all 8 bitsπ            pop     bp              ; restoreπ            ret     2               ; purge stack & returnπHex2Bin     endpπcode        endsπ            endπ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ππ Here's the assembled OBJ File ...ππ Put all of this remaining message in a Text File named HEX2Bin.SCR,π then Type "DEBUG < HEX2Bin.SCR" (no quotes) to create HEX2Bin.ARC;π then extract HEX2Bin.OBJ using PKUNPAK or PAK ...π ---------------------------- DEBUG script ----------------------------π N HEX2Bin.ARCπ E 0100 1A 02 48 45 58 32 42 49 4E 2E 4F 42 4A 00 5E 65 00 00 00 4A 19π E 0115 13 22 60 F2 65 00 00 00 80 0D 00 0B 68 65 78 32 62 69 6E 2E 41π E 012A 53 4D A9 96 07 00 00 04 43 4F 44 45 44 98 07 00 20 1D 00 02 02π E 013F 01 1F 90 0E 00 00 01 07 48 45 58 32 42 49 4E 00 00 00 6A 88 04π E 0154 00 00 A2 01 D1 A0 21 00 01 00 00 55 8B EC C4 7E 06 FC B9 08 00π E 0169 8A C1 AA 8A 66 04 32 C0 D1 C0 0C 30 AA E2 F7 5D C2 02 00 21 8Aπ E 017E 02 00 00 74 1A 00π Rcxπ 0084π Wπ Qπ ----------------------------------------------------------gbug-1.0b--π                13     05-28-9313:53ALL                      SWAG SUPPORT TEAM        HEXCONV.PAS              IMPORT              7           Varπ  n    : Word;π  long : LongInt;ππFunction Byte2Hex(numb : Byte): String;       { Converts Byte to hex String }π  Constπ    HexChars : Array[0..15] of Char = '0123456789ABCDEF';π  beginπ    Byte2Hex[0] := #2;π    Byte2Hex[1] := HexChars[numb shr  4];π    Byte2Hex[2] := HexChars[numb and 15];π  end; { Byte2Hex }ππFunction Numb2Hex(numb: Word): String;        { Converts Word to hex String.}π  beginπ    Numb2Hex := Byte2Hex(hi(numb))+Byte2Hex(lo(numb));π  end; { Numb2Hex }ππFunction Long2Hex(L: LongInt): String;     { Converts LongInt to hex String }π  beginπ    Long2Hex := Numb2Hex(L shr 16) + Numb2Hex(L);π  end; { Long2Hex }πππbeginπ  long := 65536;π  n    := 256;π  Writeln(Long2Hex(long));π  Writeln(Numb2Hex(n));πend.π                                    14     05-28-9313:53ALL                      SWAG SUPPORT TEAM        HEXINFO.PAS              IMPORT              13          > I am learning Pascal and don't understand something.  How does theπ> following Function make a Word into Hex:ππ It's Really doing two things, it's converting a binary valueπ into ascii, and from decimal to hex.  Let's start With theπ calling or main part of the Program.  You're taking a 2 Byteπ Word and breaking it up into 4 nibbles of 4 bits each.  Each ofπ these nibbles is displayed as a Single hex Character 0-F.ππ                                   Hex Representation XXXXπ                                                      ||||πHexStr := HexStr + Translate(Hi(W) shr 4); -----------||||πHexStr := HexStr + Translate(Hi(W) and 15);------------|||πHexStr := HexStr + Translate(Lo(W) shr 4); -------------||πHexStr := HexStr + Translate(Lo(W) and 15);--------------|πππNow the translate Function simply converts the decimal value ofπthe 4-bit nibble into an ascii hex value.  if you look at anπascii Chart you will see how this is done:ππ'0' = 48   '5' = 53    'A' = 65π'1' = 49   '6' = 54    'B' = 66π'2' = 50   '7' = 55    'C' = 67π'3' = 51   '8' = 56    'D' = 68π'4' = 52   '9' = 57    'E' = 69π                       'F' = 70πππAs you can see it easy For 0-9, you just add 48 to the value andπit's converted, but when you go to convert 10 to A, you need toπuse a different offset, so For values above 9 you add 55.ππFunction Translate(B : Byte) : Char;π  beginπ  if B < 10 thenπ    Translate := Chr(B + 48)π  elseπ    Translate := Chr(B + 55);π  end;π                                                                        15     05-28-9313:53ALL                      SWAG SUPPORT TEAM        RANDOM1.PAS              IMPORT              15          {Another method to acComplish this (which only requires an order of nπitterations is to generate an Array initialized from 2 to 1000 and thenπrandomize that Array.  For your 400 numbers, just take 400 values in theπnew sequence (starting at the index of your lowest number). You can doπthat as follows:π}ππConst MaxNumber = 2000;πType SeqArray = Array [1..MaxNumber] of Integer;ππ{================================================================}πProcedure RandomizeSeq (first, last: Integer; Var iseq: SeqArray);π{================================================================}ππVar           i, iran,π           temp, imax : Integer;π                    r : Real;π{π  Operation:  A random number within the range 1..last is generatedπ  on each pass and the upper limit of the random number generated isπ  decreased by 1.  The value stored at the highest index of the lastπ  pass is moved to the location of the last number selected.ππ  Parameters:π    first = lowest number in sequence.π     last = highest number in sequence.π     iseq = Sequence Arrayπ}πbeginπ   { initialize sequence Array }π   For i := first to last do iseq[i] := i;π   Randomize;π   { randomize the sorted Array }π   For imax := last downto first do beginπ      { get a random number between 0 and 1 and scale up toπ        an Integer in the range of first to last }π      r := random;π      iran := Trunc(r*imax) + first;π      { replace With value at highest index }π      temp := iseq[iran];π      iseq[iran] := iseq[imax];π      iseq[imax] := tempπ   end;πend;ππ{ Example of generating 20 random numbers from 2 to 100: }ππVar i : Integer;π    a : SeqArray;πbeginπ   RandomizeSeq(2,100,a);π   For i := 2 to 21 do Write(a[i]:3); Writeln;πend.π                                                                       16     05-28-9313:53ALL                      SWAG SUPPORT TEAM        RANDOM2.PAS              IMPORT              18          { MR> I have started playing With Borland Turbo Pascal 7.0 and I have aπ MR> problem. The Random routine is not the same as the one in TP 6.0.π MR> Using the same RandSeed, they generate different series of numbers.π MR> I have a couple of applications that depend upon the number seriesπ MR> generated by the TP 6.0 version. Can anyone supply me With theπ MR> algorithm used in the TP 6.0 Random routine? or maybe point me inπ MR> the right direction? I want to Construct my own TP 7 Random routineπ MR> that will behave as the one in TP 6.ππThe way both generators work is to update System.Randseed, then calculate theπnew random value from that one.  There have been several different ways toπcalculate the value; I think TP 6 is different from TP 5.5, and TP 7 isπdifferent again.  The update algorithm has been pretty Constant.ππAs I recall, you can simulate the TP 6 Random(N) Function in TP 7 as follows:π}πFunction TP6Random(N:Word):Word;πVarπ  junk : Word;π  myrandseed : Recordπ  lo, hi : Wordπ  end Absolute system.randseed;πbeginπ  junk := Random(0);   { Update Randseed }π  TP6Random := myrandseed.hi mod N;πend;ππ{πYou might want to keep the following around in Case the update algorithm getsπchanged sometime in the future:ππDemonstration Program to show how the TP 6.0 random number generatorπupdates System.Randseed.  Allows the seed to be cycled backwards. }ππProcedure CycleRandseed(cycles:Integer);π{ For cycles > 0, mimics cycles calls to the TP random number generator.π  For cycles < 0, backs it up the given number of calls. }πVarπ  i : Integer;πbeginπ  if cycles > 0 thenπ    For i := 1 to cycles doπ      system.randseed := system.randseed*134775813 + 1π  elseπ    For i := -1 downto cycles doπ      system.randseed := (system.randseed-1)*(-649090867);πend;ππVarπ  i : Integer;πbeginπ  randomize;π  Writeln('Forwards:');π  For i:=1 to 5 doπ    Writeln(random);π  Writeln('Backwards:');π  For i:=1 to 5 doπ  beginπ    CycleRandseed(-1);    { Back to previous value }π    Writeln(random);      { Show it }π    CycleRandseed(-1);    { Back up over it again }π  end;πend.π                                                                                  17     05-28-9313:53ALL                      SWAG SUPPORT TEAM        REALFRMT.PAS             IMPORT              8           {π  I recently came across the need For a way to dynamically Formatπ  Real Variables For output - I came out With the following. (Youπ  people following the Compiler thread may want this to make yourπ  Compiler output pretty)ππ  The routine checks to see how big the exponent is; if it's biggerπ  than 1E7 or smaller than 1E-7, an unFormatted conversion is made.π  if the number is less than 1E7 and greater than 1E-7, then aπ  Formatted String is created. to make the output prettier, trailingπ  zeros, periods and leading spaces are deleted.π}ππFunction FormatReal(r:Real):String;πVarπ  s :String;ππbeginπ  if ((r>1E-7) and (r<1E7))thenπ    Str(r:12:12, s)π  elseπ    Str(r, s);ππ  While s[ord(s[0])]='0' doπ    Delete(s, ord(s[0]), 1);π  While (s[1]=' ') doπ    Delete(s, 1, 1);π  if s[ord(s[0])]='.' thenπ    Delete(s, ord(s[0]), 1);ππ  FormatReal := s;πend;π                                 18     05-28-9313:53ALL                      SWAG SUPPORT TEAM        REVERSE.PAS              IMPORT              7           {π a problem.  I am asked to find the reverse of a positive Integer.  Forπ example the reverse of 123 is 321 or the reverse of 1331 is 1331.π My teacher said that we should use div and MOD.π}ππVarπ  X, Y: Integer;ππbeginπ  X := PositiveInteger;π  Y := 0;ππ  While X > 0 doπ  beginπ    Y := (Y * 10) + (X mod 10);π    X := X div 10;π  end;ππ{πThe result will be in Y.  Just so you do learn something of use out of this: Itπis a fact that the difference between two transposed (reversed) numbers will beπevenly divisible by 9. This can be of help if you are doing somethingπaccounting related and are trying to figure out why your numbers don't jive. ifπthe amount you are out is evenly divisible by 9, it is most likely aπtransposing error.π}π                          19     05-28-9313:53ALL                      SWAG SUPPORT TEAM        ROMAN1.PAS               IMPORT              19          {π·    Subject: Word to Roman Numeralππ  OK, here is my second attempt, With error checking and all. Thanks toπTerry Moore <T.Moore@massey.ac.nz> For encouraging me. The last Functionπalso contained a couple of errors. This one is errorchecked.π}ππFunction RomantoArabic(Roman : String) : Integer;π{ Converts a Roman number to its Integer representation }π{ Returns -1 if anything is wrong }ππ  Function Valueof(ch : Char) : Integer;π  beginπ    Case ch ofπ      'I' : Valueof:=1;π      'V' : Valueof:=5;π      'X' : Valueof:=10;π      'L' : Valueof:=50;π      'C' : Valueof:=100;π      'D' : Valueof:=500;π      'M' : Valueof:=1000;π      else Valueof:=-1;π    end;π  end;   { Valueof }ππ  Function AFive(ch : Char) : Boolean; { Returns True if ch = 5,50,500 }π  beginπ    AFive:=ch in ['V','L','D'];π  end;   { AFive }ππVarπ  Position : Byte;π  TheValue, CurrentValue : Integer;π  HighestPreviousValue : Integer;πbeginπ  Position:=Length(Roman); { Initialize all Variables }π  TheValue:=0;π  HighestPreviousValue:=Valueof(Roman [Position]);π  While Position > 0 doπ  beginπ    CurrentValue:=Valueof(Roman [Position]);π    if CurrentValue<0 thenπ    beginπ      RomantoArabic:=-1;π      Exit;π    end;π    if CurrentValue >= HighestPreviousValue thenπ    beginπ      TheValue:=TheValue+CurrentValue;π      HighestPreviousValue:=CurrentValue;π    endπ    elseπ    begin { if the digit precedes something larger }π      if AFive(Roman [Position]) thenπ      beginπ          RomantoArabic:=-1; { A five digit can't precede anything }π          Exit;π      end;π      if HighestPreviousValue div CurrentValue > 10 thenπ      beginπ          RomantoArabic:=-1; { e.g. 'XM', 'IC', 'XD'... }π          Exit;π      end;π      TheValue:=TheValue-CurrentValue;π    end;π    Dec(Position);π  end;π  RomantoArabic:=TheValue;πend;   { RomantoArabic }ππbeginπ  Writeln('XXIV = ', RomantoArabic('XXIV'));π  Writeln('DXIV = ', RomantoArabic('DXIV'));π  Writeln('CXIV = ', RomantoArabic('CXIV'));π  Writeln('MIXC = ', RomantoArabic('MIXC'));π  Writeln('MXCIX = ', RomantoArabic('MXCIX'));π  Writeln('LXVIII = ', RomantoArabic('LXVIII'));π  Writeln('MCCXXIV = ', RomantoArabic('MCCXXIV'));π  Writeln('MMCXLVI = ', RomantoArabic('MMCXLVI'));π  Readln;πend.                                                                              20     05-28-9313:53ALL                      SWAG SUPPORT TEAM        ROMAN2.PAS               IMPORT              10          {π>Anyone know of how to make a Program that will convert anyπ>Integer entered into roman numeral Format?π}ππProgram Roman_Numeral_Test;ππTypeπ  st_4 = String[4];π  st_15 = String[15];π  star_4 = Array[0..3] of st_4;π  star_10 = Array[0..9] of st_4;ππConstπ  Wunz : star_10 = ('', 'I', 'II', 'III', 'IV',π                    'V', 'VI', 'VII', 'VIII', 'IX');ππ  Tenz : star_10 = ('', 'X', 'XX', 'XXX', 'XL',π                    'L', 'LX', 'LXX', 'LXXX', 'XC');ππ  Hunz : star_10 = ('', 'C', 'CC', 'CCC', 'CD',π                    'D', 'DC', 'DCC', 'DCCC', 'CM');ππ  Thouz : star_4 = ('', 'M', 'MM', 'MMM');πππFunction Dec2Roman(wo_in : Word) : st_15;πbeginπ  Dec2Roman := Thouz[(wo_in div 1000)] +π               Hunz[((wo_in mod 1000) div 100)] +π               Tenz[(((wo_in mod 1000) mod 100) div 10)] +π               Wunz[(((wo_in mod 1000) mod 100) mod 10)]πend;ππVarπ  wo_Temp : Word;ππbeginπ  Writeln;π  Write(' Enter number to be converted to roman-numeral equivalent: ');π  readln(wo_Temp);π  if (wo_Temp > 3999) thenπ    wo_Temp := 3999;π  Writeln;π  Writeln(' Roman-numeral equivalent of ', wo_Temp, ' = ', Dec2Roman(wo_Temp))πend.ππ        21     05-28-9313:53ALL                      SWAG SUPPORT TEAM        SHLSHR.PAS               IMPORT              24          { INFO ON SHR and SHL }ππ> (5 Shl 2) + 5 which is: (5 x 4) + 5π> So, 10 * 10 would be (10 Shl 3) + (10 Shl 1)ππThis looks good but, can it be done With Variables (So I can useπnumbers other than 5 & 5)?ππ Yes, just keep in mind that each shift leftward Doubles the value...ππ        p SHL 1  =  p * 2π        p SHL 2  =  p * 4π        p SHL 3  =  p * 8π        p SHL 4  =  p * 16π        ...ππ (likewise, each shift rightward halves the value).ππ Also keep in mind that the maximum amount you can shift is theπ number of bits in the Variable.  Bytes are 8 bits, Words andπ Integers are 16 bits, and LongInts are 32 bits.  if you shiftπ a Variable its full bit size, or more, it will be 0 (zero).ππ For example: if p is a Byte, then p SHR 8 = 0.ππ{  Use Shr/Shl to multiply/divide, rather than the operatorsπ  How do you (or anybody) do this?   For example, how would I do 5 * 5?π}π{*******************************************************************}π Program DemoShifts;π Var     Number, Result  : Word;π beginπ    {   Calculate 5 * 5, without using multiplication ...           }ππ    Number := 5;                    { original value                }π    Result := Number SHL 2;         { now Result = 4 * Number       }π    Result := Result + Number;      { 4*Number + Number = 5*Number  }ππ    WriteLn( '5 * 5 = ', Result );  { because seeing is believing   }ππ end {DemoShifts}.π{*******************************************************************}ππ But TP seems sometimes to do the 'shift vs. MUL optimization' itself,π this being bad if Compiling For a 386/486 CPU.π A "* 2" would always result in a SHL instruction ( unless Realπ arithmetic was used ;-> ).ππ Ok, I understand that part.  if x shr 4 = x/4  (and the remainder isπ dropped) then I Really understand it.  Does it? Do I?ππNo.  x shl 0 = xπ     x shl 1 = x/(2^1) = x/2π     x shl 2 = x/(2^2) = x/4π     x shl 3 = x/(2^3) = x/8π     x shl 4 = x/(2^4) = x/16ππJust as:π     x shr 0 = xπ     x shr 1 = x*(2^1) = 2xπ     x shr 2 = x*(2^2) = 4xπ     x shr 3 = x*(2^3) = 8xπ     x shr 4 = x*(2^4) = 16xππSo now you can see how and why the Compiler substitutes a "shr 1" For "* 2".ππ > PD> So, 10 * 10 would be: (10 shl 3) + 20π >π > MC> not quite:π > MC> (10 Shl 3)+(10 Shl 1)s, I'm back! (3:634/384.6)π >π > Why?  wouldn't the second one take an additional instruction (shl)?ππWell yes, but 8086 instructions weren't created equal.  PerForming twoπshifts and the add to combine them will (on a 286 or lesser) less timeπoverall than doing even one MUL.ππThe 386/486 has streamlined the MUL instruction so that it takes much lessπtime, and can often Compete With the shift/add approach.  Which to use?πWell, I'd stick With the shift/add approach, since if you're writing oneπProgram For both XTs and 386s, the XT will be acceptable, and so will theπ386.  Using the MUL; True, 386 perFormance will be better, but your XTπperFormance will suffer quite a bit.π                        22     05-28-9313:53ALL                      SWAG SUPPORT TEAM        SWAPNUMS.PAS             IMPORT              5           {π>Is there a way (using bit manipulations such as AND, OR, XOR) toπ>swap to Variables without making a 3rd temporary Variable?π>ππIf the two Variables are numbers, and the following operationsπwon't overflow the limitations of the Type, then yes, you canπdo it like this:π}πVarπ   A, B : Integer;ππbeginπ   A := 5;π   B := 3;ππ   A := A + B;π   B := A - B;π   A := A - B;ππ   { which isππ   A := 5 + 3 (8)π   B := 8 - 3 (5)π   A := 8 - 5 (3)ππ   A = 3π   B = 5 }ππend;                                           23     05-28-9313:53ALL                      SWAG SUPPORT TEAM        TP6RAND.PAS              IMPORT              12          {πBorland changed the Random() algorithm between TP6 and TP/BP7.  The Unitπbelow provides the TP6 Random Function in its Integer flavour.  (TheπRandomize Procedure wasn't changed.)ππ{ *  Turbo Pascal Runtime Library Version 6.0     * ;π  *  Random Number Generator                      * ;π  *                                               * ;π  *  Copyright (C) 1988,92 Borland International  * }ππUnit TP6Rand;ππInterfaceππFunction Random(Max: Integer): Integer;ππImplementationππConstπ  { Scaling Constant}π  ConstM31 = LongInt(-31);π  { Multiplication factor}π  Factor: Word = $8405;πππFunction NextRand: LongInt; Assembler;π{π  Compute next random numberπ  New := 8088405H * Old + 1π  Out  DX:AX = Next random numberπ}πAsmπ  MOV  AX,RandSeed.Word[0]π  MOV  BX,RandSeed.Word[2]π  MOV  CX,AXπ  MUL  Factor.Word[0]     { New = Old.w0 * 8405H }π  SHL  CX,1               { New.w2 += Old.w0 * 808H }π  SHL  CX,1π  SHL  CX,1π  ADD  CH,CLπ  ADD  DX,CXπ  ADD  DX,BX              { New.w2 += Old.w2 * 8405H }π  SHL  BX,1π  SHL  BX,1π  ADD  DX,BXπ  ADD  DH,BLπ  MOV  CL,5π  SHL  BX,CLπ  ADD  DH,BLπ  ADD  AX,1      { New += 1 }π  ADC  DX,0π  MOV  RandSeed.Word[0],AXπ  MOV  RandSeed.Word[2],DXπend;ππFunction Random(Max: Integer): Integer; Assembler;πAsmπ CALL  NextRandπ xor   AX,AXπ MOV   BX,Max.Word[0]π or    BX,BXπ JE    @@1π XCHG  AX,DXπ div   BXπ XCHG  AX,DXπ@@1:πend;ππend.π                               24     05-28-9313:53ALL                      SWAG SUPPORT TEAM        WORD2HEX.PAS             IMPORT              67          {π> How does the following Function make a Word into Hex:ππ - Dissection:π}ππTypeπ  Str4 : String[4];ππFunction WordtoHex(W : Word) : St4πVarπ  HexStr : St4;ππ  Function Translate(B : Byte) : Char;ππ  { This Function takes a number from 0 to 15 and makes it into a hex digit.}ππ  beginπ    if B < 10 thenπ    { if it's 0..9 }π      Translate := Chr(B + 48)π  { These statements use math on Characters... ascii 48 is '0'.π    Could have been written: Translate := Chr(B + ord('0')) }π    elseπ      Translate := Chr(B + 55);π  { This one is For letters A~F. ascii 55 isn't anything, but if you addπ    $A (10) to 55 you get 65, which is the ascii code For 'A'π    This could have been written: Translate := Chr(B + ord('A')-$A); }π  end;ππbeginπ  HexStr := ' ';π  HexStr := HexStr + Translate(Hi(W) shr 4);π  { Hi(W) takes the high Byte of Word W.π    shr 4 means the same as divide by 16...π    What they're Really doing here is taking each nibble of the hex Wordπ    and isolating it, translating it to hex, and adding it to the String. }π  HexStr := HexStr + Translate(Hi(W) and 15);π  HexStr := HexStr + Translate(Lo(W) shr 4);π  HexStr := HexStr + Translate(Lo(W) and 15);π  WordtoHex := HexStr;πend;π{π> I am learning Pascal and don't understand something.  Howπ> does the following Function make a Word into Hex:ππIt doesn't, at least not as present! But if you changes two things, maybeπspelling-errors, it will work. This is a bit hard to explain and grasp, becauseπit involves operations at a less abstract level than the one that you usuallyπwork on in TP. Remember, when a number is stored in memory, it's stored binary,πhexadecimal notion is just For making it easier For man to read. I don't knowπif you know how to Write and read binary- and hexadecimal-numbers, in Case youπdon't know it's all here...ππOn PC, a Word, in the range 0 to 65535, has 16 bits. A Word written in binaryπnotion For this reason contains 16 digits, 0's or 1's! But a Word written inπhexadecimal notion contains 4 digits. Simple math tells us that one digit inπhex-notion is equal to four digits binary. Four digits binary gives 16πcombinations (2^4). ThereFore, each hexadecimal digit must be able to containπvalues from decimal 0-decimal 15, _in one digit_! Our normal digits, 0-9, isn'tπsufficient For this, we must use 6 other digits. The designers of this systemπchoosed A-F as the extra digits. This means, in hex the digits are 0, 1, 2, 3,π4, 5, 6, 7, 8, 9, A, B, C, D, E and F. Hanging on?ππ>    Function WordtoHex(W : Word) : St4ππCompile-time error: You must have a semicolon after the Function header-line.ππ>    Varπ>        HexStr : St4;ππ>        Function Translate(B : Byte) : Char;π>        beginπ>           if B < 10π>               thenπ>                   Translate := Chr(B + 48)π>               elseπ>                   Translate := Chr(B + 55);π>        end;ππThis is clearer as:ππ  if b < 10π    then Translate := Chr(b+ord('0'))π    else Translate := Chr(b+ord('A')-10);ππThink about the first Case, when b < 10, if b were 0, the expression would beπ'0' plus 0, '0'!. if b were 1, it's '0' plus 1, '1'!. This works because in theπASCII-table the numbers are sequential ordered. But '0' plus 10 would be ':',πbecause it happens to be after the numbers.ππthen, when we want 'A'-'F, we would need to start from 'A'. But we can't add 10πto 'A' For getting 'A' and 11 For getting 'B' and that like. First we must makeπthe value relative 'A'. Because the values that we're working on here is in theπrange 10 to 15, we can decrease it With 10 and get 0 to 5. then is OK to useπthem relative 'A'. As beFore, 'A' plus 0 is 'A', 'A' plus 1 is 'B', and so on.ππHowever, this routine has no safety check, it will gladly return 'G' For 16,πbecause 'A'+6 is 'G'. It doesn't care if the value is within hexadecimal rangeπor not (numbers bigger than 15 can't be turned into one hex digit, they needπmore digits). But here it's OK, because the routine is local to WordtoHex thatπwill never pass anything else than 0 to 15.ππ>    beginπ>        HexStr := ' ';ππLogical error: You must initalize HexStr to an empty String, '', if not it willπconsist of a space and three hex digits, not four. A hex-Word String isπComposed of four hexadeciamal-digits. Because you have declared the String as aπVariable of the Type St4 and St4 only allows four Chars, exactly what is neededπFor a hexWord-String, the last one added will be discarded if you have a spaceπat the beginning, filling up one position.ππ>        HexStr := HexStr + Translate(Hi(W) shr 4);π>        HexStr := HexStr + Translate(Hi(W) and 15);π>        HexStr := HexStr + Translate(Lo(W) shr 4);π>        HexStr := HexStr + Translate(Lo(W) and 15);π>        WordtoHex := HexStr;π>    end;ππIt would be easier to read if the 'and'-value were in hex-notation, $000F. Seeπbelow For explanation why. However, this part requires some understanding ofπthe bits. It's probably best show With an example. Let's say, our number W isπ$1234.ππ$1234 is written 0001 0010 0011 0100 in binary. Each hex-digit corresponds to aπfour-group binary digits.ππ■) The binary number 0001 is 0*(2^3) + 0*(2^2) + 0*(2^1) + 1*(2^0). It givesπ0+0+0+1=1 in decimal.ππ■) The binary number 0101 is 0*(2^3) + 1*(2^2) + 0*(2^1) + 1*(2^0). It givesπ0+4+0+1=5 in decimal.ππ■ The _decimal_ number 1101 is 1*(10^3) + 1*(10^2) + 0*(10^1) + 1*(10^0). Itπgives 1000+100+0+1=1011! As you can see, the only difference between theπdecimal and the binary and the hexadecimal system is the base-power. True, theπhex-system Uses strange digits For us used to decimal, but For the ones used toπbinary, 2-9 is equally strange...ππLike our decimal system, in hex and binary, it's unnescessary to includeπleading zeros, i. e. $0001 = $1 (of course you can't remove trailing zeroes,πdecimal 1000 certainly isn't equal to decimal 1...). But you will note that Iπsometimes include these leading zeroes, just because it looks good (?). andπwriting binary number 1000 0000 is like writing 10000 in decimal as 10,000;πit's only For easy reading, but the Compiler won't allow it.ππHowever, I hope you grasp a least something of my extremly bad explanation :-(,πor maybe you know it beFore?! Now, let's look at the things that happens whenπthe above statements are executed and w = $1234 (0001 0010 0011 0100).ππHi returns the upper 8 bits of the Word, in this Case 0001 0010; Lo returns theπlower bits (!), 0011 0100. The above code Uses 'and' and 'shr', a breifπexplanation of them will probably be nescessary (oh no :-)).ππ■ and, when not used as a Boolean operator, Uses two binary numbers and, Forπeach bit, tests them. if _both_ bits are set (equal to 1) the resuling bit isπset to 1, if any or both of them is cleared (equal to 0) the result is 0. Thisπmeans:πππ  0001 0010   Hi(w)                     0011 0100   Lo(w)π  0000 1111   and With 15 or $000F      0000 1111   and With 15 or $000Fπ  ---------                             ---------π  0000 0010   0010 binary = 2 hex       0000 0100   0100 binary = 4 hexππThis was the second and first statement, and out you get the second and firstπnumber! When we pass them to Translate, we get back '2' and '4'.ππ■ shr, only For binary operations, shifts the bits to the right. The bits thatπpasses over the right side is lost, and the ones that move on left side isπreplaced by zeroes. The bits shifts as many times as the value after theπshr-keyWord, here 4 times. Like this:ππ  00010010   Hi(w)                     00110100   Lo(w)π  --------             shr 4           --------π  00001001        after one shift      00011010π  00000100        after two shifts     00001101π  00000010       after three shifts    00000110π  00000001       after four shifts     00000011ππNow we got binary 0001 and binary 0011, in hex $1 and $3. The first and thirdπstatement, and the first and third number! The String to return is digit1 +πdigit2 + digit3 + digit4, exactly what we want.ππHmm... Now I haven't told you anything about the binary or, xor, not andπshl-keyWords... But I think this message is quiet long as it is, without that.πBut if you want more info or a better explanation, only drop me a msg here.ππHappy hacking /Jake 930225 17.35 (started writing last night)πPS. There may be some errors, I haven't proof-read the Text or my math. then,πplease correct me, anybody.π}